package mapper

import (
	"context"
	"fmt"
	"newsletter-subs/pkg/db"
	"newsletter-subs/pkg/model"
	"time"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type MongoSubscription struct{}

var MSubscription = &MongoSubscription{}

func (m *MongoSubscription) Create(p *model.MSubscription) (err error) {
	// 插入文档
	if _, err = db.GetColl().InsertOne(context.Background(), p); err != nil {
		return
	}
	fmt.Println("Document inserted successfully!")
	return
}

func (m *MongoSubscription) CreateMany(p []interface{}) error {

	// 插入多条文档
	if _, err := db.GetColl().InsertMany(context.Background(), p); err != nil {
		return err
	}
	fmt.Println("Document inserted successfully!")
	return nil
}

func (m *MongoSubscription) Delete(p string) error {

	// 过滤条件
	id, _ := primitive.ObjectIDFromHex(p)
	fil := bson.M{"_id": id}

	// 删除文档
	if _, err := db.GetColl().DeleteOne(context.Background(), fil); err != nil {
		return err
	}
	fmt.Println("Document Delete successfully!")
	return nil
}

func (m *MongoSubscription) Update(p *model.MSubscription) error {

	// 根据条件筛选要更新的文档
	id, _ := primitive.ObjectIDFromHex(p.Id)
	filter := bson.M{"_id": id}
	update := bson.M{"$set": bson.M{"name": p.Name, "description": p.Description, "email": p.Email, "phone": p.Phone, "updated_at": time.Now()}}

	// 更新文档
	if _, err := db.GetColl().UpdateOne(context.Background(), filter, update); err != nil {
		return err
	}
	fmt.Println("Document Update successfully!")
	return nil
}

func (m *MongoSubscription) Find(p string) (subs model.MSubscription, err error) {
	id, _ := primitive.ObjectIDFromHex(p)
	filter := bson.M{"_id": id} // 根据条件筛选要更新的文档

	err = db.GetColl().FindOne(context.Background(), filter).Decode(&subs)
	if err != nil {
		return
	}

	fmt.Println("Document Find successfully!")
	fmt.Printf("Document Find: %+v", subs)

	return
}

func (m *MongoSubscription) FindAll() (subs []model.MSubscription, err error) {

	// 插入文档
	cur, err := db.GetColl().Find(context.Background(), bson.M{})
	if err != nil {
		return nil, err
	}

	if err = cur.All(context.Background(), &subs); err != nil {
		return nil, err
	}

	fmt.Println("Document Find successfully!")
	for _, s := range subs {
		fmt.Printf("Document found: %+v\n", s)
	}

	return subs, nil
}

// Query 分页查询 select * from stu limit ?
func (m *MongoSubscription) Query(size int64) (subs *[]model.Subscription, err error) {

	// 分页选项
	l := options.Find().SetLimit(size)
	filter := bson.M{}
	// 插入文档
	res, err := db.GetColl().Find(context.TODO(), filter, l)
	if err != nil {
		return
	}

	fmt.Println("Document Find successfully!")
	defer res.Close(context.Background())

	if err = res.All(context.Background(), subs); err != nil {
		return
	}
	for _, s := range *subs {
		fmt.Printf("Document found: %+v\n", s)
	}
	return
}

// QueryStudent2 对查询结果进行降序排序，入参为1升序，入参-1降序
func (m *MongoSubscription) QueryByDesc(p int) (subs *[]model.Subscription, err error) {
	// select * from stu order by age desc
	// 排序选项
	s := options.Find().SetSort(bson.D{{"_id", p}})
	filter := bson.M{}

	// 3.插入文档
	res, err := db.GetColl().Find(context.TODO(), filter, s)
	if err != nil {
		return
	}

	fmt.Println("Document Find successfully!")
	defer res.Close(context.Background())

	if err = res.All(context.Background(), subs); err != nil {
		return
	}
	for _, s := range *subs {
		fmt.Printf("Document found: %+v\n", s)
	}

	return
}

// QueryStudent3 模糊查询 select * from stu where name like %?%
func (m *MongoSubscription) QueryLike(p string) (subs *[]model.Subscription, err error) {
	filter := bson.M{
		"name": bson.M{
			"$regex": p,
		},
	}

	// 查询
	res, err := db.GetColl().Find(context.TODO(), filter)
	if err != nil {
		return
	}

	fmt.Println("Document Find successfully!")
	defer res.Close(context.Background())

	if err = res.All(context.Background(), subs); err != nil {
		return
	}

	for _, s := range *subs {
		fmt.Printf("Document found: %+v\n", s)
	}
	return
}

// QueryStudent6 连接查询 select * from stu where age = ? and name = ?
func (m *MongoSubscription) QueryAnd(mail string, name string) (subs *[]model.Subscription, err error) {
	// 过滤条件
	filter := bson.M{
		"$and": []bson.M{
			{"name": name},
			{"mail": mail},
		},
	}

	// 查询
	res, err := db.GetColl().Find(context.TODO(), filter)
	if err != nil {
		return
	}

	fmt.Println("Document Find successfully!")
	defer res.Close(context.Background())

	if err = res.All(context.Background(), subs); err != nil {
		return
	}

	for _, s := range *subs {
		fmt.Printf("Document found: %+v\n", s)
	}
	return
}
